package com.uziot.bucket.ftp.transfer;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Random;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TransferClient {

    private static final ArrayList<String> FILE_LIST = new ArrayList<String>();

    private static final String SEND_FILE_PATH = Constants.SEND_FILE_PATH;

    /**
     * 带参数的构造器，用户设定需要传送文件的文件夹
     *
     * @param filePath filePath
     */
    public TransferClient(String filePath) {
        getFilePath(filePath);
    }

    /**
     * 不带参数的构造器。使用默认的传送文件的文件夹
     */
    public TransferClient() {
        getFilePath(SEND_FILE_PATH);
    }

    public void service() {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Vector<Integer> vector = getRandom(FILE_LIST.size());
        for (Integer integer : vector) {
            String filePath = FILE_LIST.get(integer);
            executorService.execute(sendFile(filePath));
        }
    }


    private void getFilePath(String dirPath) {
        File dir = new File(dirPath);
        File[] files = dir.listFiles();
        if (files == null) {
            return;
        }
        for (File file : files) {
            if (file.isDirectory()) {
                getFilePath(file.getAbsolutePath());
            } else {
                FILE_LIST.add(file.getAbsolutePath());
            }
        }
    }

    private Vector<Integer> getRandom(int size) {
        Vector<Integer> v = new Vector<>();
        Random r = new Random();
        boolean b = true;
        while (b) {
            int i = r.nextInt(size);
            if (!v.contains(i)) {
                v.add(i);
            }
            if (v.size() == size) {
                b = false;
            }
        }
        return v;
    }

    private static Runnable sendFile(final String filePath) {
        return new Runnable() {

            private Socket socket = null;
            private String ip = "localhost";
            private int port = 10001;

            @Override
            public void run() {
                System.out.println("开始发送文件:" + filePath);
                System.out.println(Thread.currentThread().getName());
                File file = new File(filePath);
                if (createConnection()) {
                    int bufferSize = 8192;
                    byte[] buf = new byte[bufferSize];
                    try {
                        DataInputStream fis = new DataInputStream(new BufferedInputStream(new FileInputStream(filePath)));
                        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());

                        dos.writeUTF(file.getName());
                        dos.flush();
                        dos.writeLong(file.length());
                        dos.flush();

                        int read = 0;
                        long passedlen = 0;
                        long passedlen1 = 0;
                        long length = file.length();    //获得要发送文件的长度
                        while ((read = fis.read(buf)) != -1) {
                            passedlen += read;
                            dos.write(buf, 0, read);
                            if ((passedlen * 100L / length) == passedlen1) {
                                continue;
                            }
                            System.out.println("已经完成文件 [" + file.getName() + "]百分比: " + passedlen * 100L / length + "%");
                            passedlen1 = passedlen * 100L / length;
                        }

                        dos.flush();
                        fis.close();
                        dos.close();
                        socket.close();
                        System.out.println("文件 " + filePath + "传输完成!");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            private boolean createConnection() {
                try {
                    socket = new Socket(ip, port);
                    System.out.println("连接服务器成功！");
                    return true;
                } catch (Exception e) {
                    System.out.println("连接服务器失败！");
                    return false;
                }
            }

        };
    }

    public static void main(String[] args) {
        new TransferClient().service();
    }
}